class eventsEmitter {
  constructor() {
    this.events = {}
  }
  on(name, fn) {
    if (this.events[name]) {
      this.events[name].push(fn)
    } else {
      this.events[name] = [fn]
    }
  }
  once(name, fn) {
    const once = (...args) => {
      fn(...args)
      this.off(name, once)
    }
    once.callback = fn
    this.on(name, once)
  }
  off(name, fn) {
    let tasks = this.events[name]
    if (tasks) {
      const index = tasks.findIndex(f => f === fn || f.callback === fn)
      if (index >= 0) {
        tasks.splice(index, 1)
      }
    }
  }
  emit(name, ...args) {
    if (this.events[name]) {
      let tasks = this.events[name].slice()
      tasks.forEach(fn => {
        fn(...args)
      })
    }
  }
}